
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原型</title>
</head>
<body>
    

    <script>

        // js的三座大山：  
        // 原型与原型链
        // 作用域：  闭包  this指针  垃圾回收及内存泄漏
        // 异步同步与宏任务微任务

        // 原型与原型链
        // 1. prototype
        // 每个对象（函数）都有一个prototype属性，被称为显示原型: 指向另一个对象（就是原型对象）
        // prototype =>给程序员写代码用

        // 2.__proto__
        // 每个实例对象都会有__proto__属性,其被称为隐式原型
        // 给js程序查找原型关系使用的

        // 每一个实例对象的隐式原型__proto__属性指向自身构造函数的显式原型prototype

        // 3. constructor
        // constructor在原型链中,是作为对象prototype的一个属性存在的,它指向构造函数
        // 每个prototype原型都有一个constructor属性，指向它关联的构造函数。


        // prototype
        // __proto__
        // Contructor


    // 具体理解原型链  精髓
    // 当你试图获取一个对象的某个属性时，如果这个对象本身没有这个属性，那么它会去它的隐式原型__proto__
    // （也就是它的构造函数的显示原型prototype）中查找。函数的prototype，
    // 如果还没有找到就会再在构造函数的prototype的__proto__中查找，这样一层一层向上查找就会形成一个链式结构，我们称为原型链，当然如果最终找不到返回null。)



        // Person函数 Person函数由创造 Function生产（Function构造函数）
        function Person() {
            
        }

        // 我创建了一个函数fn  这个函数由构造函数Person生成
        let  person = new Person()

        // person的__proto__（隐式原型）指向其构造函数Person的prototype
        console.log(person.__proto__ === Person.prototype );


        //每一个原型都有一个constructor属性指向关联的构造函数，实例原型指向构造函数
        console.log(Person.prototype.constructor == Person);
        

        // Person的__proto__（隐式原型）指向其构造函数Function的prototype
        console.log(Person.__proto__ === Function.prototype );


        // Function的__proto__（隐式原型）指向其构造函数Function的prototype
        console.log(Function.__proto__ === Function.prototype );



        // Function.prototype的__proto__（隐式原型）指向其构造函数Object的prototype
        // Function.prototype是一个对象,同样是一个方法,方法是函数,所以它必须有自己的构造函数也就是Object
        console.log(Function.prototype.__proto__ === Object.prototype );


         // Object作为一个构造函数(是一个函数对象!!函数对象!!),所以他的__proto__指向Function.prototype
         console.log(Object.__proto__ === Function.prototype );

         // Object.prototype作为一切的源头,他的__proto__是null
         console.log(Object.prototype.__proto__ === null );



        // obj作为一个直接以字面量创建的对象，所以obj__proto__直接指向了Object.prototype，而不需要经过Function
        let  obj = {}

        console.log(obj.__proto__ === Object.prototype);
        console.log(obj.__proto__.__proto__ === null);


        console.log(obj.__proto__.constructor === Object);
        console.log(obj.__proto__.constructor.__proto__ === Function.prototype)
        console.log(obj.__proto__.constructor.__proto__.__proto__ === Object.prototype)
        console.log(obj.__proto__.constructor.__proto__.__proto__.__proto__ === null)
        console.log(obj.__proto__.constructor.__proto__.__proto__.constructor.__proto__ === Function.prototype)    









        


    </script>

</body>
</html>